//
// Created by W.yk on 2022/5/25.
//
#include "Server.h"
#include <cstring>
#include <sstream>
#include <string>

using namespace std;

void Server::insert_value(int id, const unsigned char *c1,
                          const unsigned char *c2, const unsigned char *c3,
                          const unsigned char *c4) {
    COMPACT_DATA compactData{};
    compactData.id = id;
    memcpy(compactData.c1, c1, strlen(reinterpret_cast<const char *>(c1)) + 1);
    memcpy(compactData.c2, c2, strlen(reinterpret_cast<const char *>(c2)) + 1);
    memcpy(compactData.c3, c3, strlen(reinterpret_cast<const char *>(c3)) + 1);
    memcpy(compactData.c4, c4, strlen(reinterpret_cast<const char *>(c4)) + 1);
    int res = instance->get_root()->insert(&compactData);

}

int Server::insert_from_csv(const string &path) {
    int count = 0;
    ifstream ifs;
    ifs.open(path, ios::in);
    if (!ifs.is_open()) {
        return -1;
    }
    string temp;
    while (getline(ifs, temp, '\n')) {
        auto *c1 = new unsigned char[128];
        auto *c2 = new unsigned char[128];
        auto *c3 = new unsigned char[128];
        auto *c4 = new unsigned char[80];
        count++;
        string str;
        istringstream istr(temp);
        getline(istr, str, '\t');
        int id = atoi(str.c_str());
        getline(istr, str, '\t');
        strcpy(reinterpret_cast<char *>(c1), str.c_str());

        getline(istr, str, '\t');
        strcpy(reinterpret_cast<char *>(c2), str.c_str());

        getline(istr, str, '\t');
        strcpy(reinterpret_cast<char *>(c3), str.c_str());

        getline(istr, str, '\t');
        strcpy(reinterpret_cast<char *>(c4), str.c_str());
//    cout<<id<<" "<<c1<<" "<<c4<<endl;
        insert_value(id, c1, c2, c3, c4);
        delete[] c1;
        delete[] c2;
        delete[] c3;
        delete[] c4;
    }
    return count;
}

COMPACT_DATA *Server::search_one_piece(int value) {
    COMPACT_DATA *compactData = instance->get_root()->search(value);
    if (compactData) {
        return compactData;
    }
    return nullptr;
}

// COMPACT_DATA **Server::search_in_range(int value1, int value2) {
//     COMPACT_DATA *compactData[value2 - value1 + 1];
//     has_searched_num = instance->get_root()->search(value1, value2,
//     compactData); for (int i = 0; i < has_searched_num; i++) {
//         compactData[i]->check();
//         delete compactData[i];
//     }
//     return nullptr;
// }

vector<COMPACT_DATA> Server::search_in_range(int value1, int value2) {
    vector<COMPACT_DATA> compactData;
    compactData = instance->get_root()->search(value1, value2);
    return compactData;
}

void Server::insert_into_csv_in_range(string path, int value1, int value2) {
    ofstream outfile;
    outfile.open(path, ios::out);
    for (int i = value1; i <= value2; i++) {
        COMPACT_DATA *compactData = search_one_piece(i);
        if (compactData) {
            outfile << compactData->id << "\t";
            outfile << compactData->c1 << "\t";
            outfile << compactData->c2 << "\t";
            outfile << compactData->c3 << "\t";
            outfile << compactData->c4 << endl;
        }
    }
}

void Server::shutdown() {};

int Server::get_has_searched_num() const { return has_searched_num; }
